package com.abe.libfitness.base;

import android.os.Bundle;
import android.util.Log;

import com.abe.libfitness.entity.ComReceiveDataBean;
import com.abe.libfitness.utils.CRCChecker;
import com.abe.libfitness.utils.DataCovertUtil;
import com.abe.libfitness.utils.ProtocolV3Utils;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import android_serialport_api.SerialPort;
import butterknife.ButterKnife;

public abstract class BaseComTempActivity extends BaseActivity {
    /**
     * 测量用户最大力量:牛顿
     */
    protected static int MAX_STRENGTH = 0;
    /**
     * 测量用户拉伸距离
     */
    protected static int MAX_DISTANCE = 0;
    /**
     * 数据延迟时间
     */
    private static int mDataDelayTime = 200;
    /**
     * 拉伸状态
     */
    protected int mStatus;
    /**
     * 记录单次拉伸的最大距离，计算卡路里
     */
    protected int distance4Calorie = 0;
    /**
     * 卡路里的值
     */
    protected double calorie = 0;
    /**
     * 实际训练次数
     */
    protected int mRealCounts = 0;
    protected ComApplication mComApplication = null;
    /**
     * 发送数据线程
     */
    protected SendThread mSendThread = null;
    /**
     * 读数据线程
     */
    protected ReadThread mReadThread = null;
    protected boolean mReadEndFlag = false;
    protected boolean mSendEndFlag = false; // 发送线程停止flag
    private SerialPort mSerialPort = null;
    private OutputStream mOutputStream = null;
    private InputStream mInputStream = null;
    /**
     * 当前发送命令
     */
    private byte[] cmd = null;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ButterKnife.bind(this);
        openSerialPort();
    }

    /***
     * 初始化操作
     */
    protected void openSerialPort() {
        try {
            mComApplication = (ComApplication) getApplication();
            mSerialPort = mComApplication.getSerialPortInstance();
            if (mSerialPort != null) {
                mOutputStream = mSerialPort.getOutputStream();
                mInputStream = mSerialPort.getInputStream();
            }
        } catch (SecurityException e) {
            Log.d(TAG, "initial:" + e.toString());
        }
    }

    /**
     * 关闭串口
     */
    protected void closeSerialPort() {
        try {
            if (mOutputStream != null) {
                mOutputStream.close();
                mOutputStream = null;
            }
            if (mInputStream != null) {
                mInputStream.close();
                mInputStream = null;
            }
            if (mSerialPort != null) {
                mSerialPort.close();
                mSerialPort = null;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void send(byte[] bOutArray) {
        try {
            if (mOutputStream != null) {
                mOutputStream.write(bOutArray);
                mOutputStream.flush();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    ///设置命令发送后，等待数据接收，并判断是否接收完毕
    //应该接收到的数据判断
    //0.接收完毕 1 未收到数据
    private int isRxFinish() throws IOException {
        int rxCnt = 0;
        MyTimer mt = new MyTimer();   //用于判断是否接收完毕的定时器
        MyTimer timeout = new MyTimer();//用于判断是否超时的定时器
        timeout.Start();
        mt.Start();
        while (true) {
            switch (mInputStream.available())//判断接收的字节数
            {
                case 0://为0 没有收到数据，超过设定值后，返回接收超时
                    if (timeout.GetTimeCountMS() > 1000) {
                        return 1;
                    }
                    break;
                default://个数不为0，收到数据，10ms没有接到新数据，接收完成
                    if (rxCnt != mInputStream.available()) {
                        mt.reStart();
                        rxCnt = mInputStream.available();
                    } else {
                        if (mt.GetTimeCountMS() >= 3) {
                            return 0;
                        }
                    }
                    break;
            }
        }
    }

    protected void closeReadThread() {
        mReadEndFlag = true;
        try {
            if (mReadThread != null && mReadThread.isAlive()) {
                mReadThread.interrupt();
                mReadThread = null;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    protected void closeSendThread() {
        mSendEndFlag = true;
        try {
            if (mSendThread != null && mSendThread.isAlive()) {
                mSendThread.interrupt();
                mSendThread = null;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    protected void closeThread() {
        closeReadThread();
        closeSendThread();
    }

    protected void closeStartThread() {
        try {
            if (mSendThread != null && mSendThread.isAlive()) {
                mSendThread.interrupt();
                mSendThread = null;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    protected void onDataReceived(ComReceiveDataBean ComRecData) {
    }

    @Override
    protected void onResume() {
        super.onResume();
        mReadEndFlag = false;
        mSendEndFlag = false;
        mReadThread = new ReadThread();
        mReadThread.start();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        closeThread();
    }

    /**
     * 串口读取
     *
     * @author gzy
     */
    protected class ReadThread extends Thread {

        @Override
        public void run() {
            super.run();
            Log.d(TAG, "--------------->read start:");
            while (!isInterrupted() && !mReadEndFlag) {
                try {
                    if (mInputStream == null) {
                        return;
                    }
                    if (isRxFinish() == 0) {
                        synchronized (this) {
                            byte[] buffer = new byte[60];
                            int size = mInputStream.read(buffer);
                            if (size > 0) {
                                ComReceiveDataBean comReceiveDataBean = new ComReceiveDataBean(buffer, size);
                                Log.d(TAG, "--------------->ReadThread readData:"
                                        + DataCovertUtil.ByteArrToHex(comReceiveDataBean.bRec));
                                onDataReceived(comReceiveDataBean);// ui
                            }
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    Log.d(TAG, "ReadThread2:" + e.toString());
                    return;
                }
            }
            Log.d(TAG, "--------------->read end");
        }
    }

    class MyTimer {
        Date startDate = new Date();

        void Start() {
            startDate = new Date();
        }

        void reStart() {
            startDate = new Date();
        }

        long GetTimeCountMS() {
            return new Date().getTime() - startDate.getTime();
        }
    }


    /**
     * 发送线程
     *
     * @author gzy
     */
    protected class SendThread extends Thread {
        private boolean oneTime = true; // 只发送一次最后一条命令flag
        private Iterator<byte[]> iterator; // 命令列表迭代器
        private int retryCnt;
        private boolean isRunEnd = false;

        /**
         * 构造函数
         *
         * @param cmdList 命令列表
         * @param oneTime 是否持续发送最后一条命令
         */
        public SendThread(List<byte[]> cmdList, boolean oneTime) {
            mSendEndFlag = false;
            this.oneTime = oneTime;
            this.iterator = cmdList.iterator();
            cmd = null;
            isRunEnd = false;
        }

        public boolean isRunEnd() {
            return isRunEnd;
        }

        @Override
        public void run() {
            super.run();
            Log.d(TAG, "--------------->send start");
            while (!isInterrupted() && !mSendEndFlag) {
                try {
                    synchronized (this) {
                        retryCnt = 0;
                        if (iterator.hasNext()) { // 迭代器中有下一条命令？
                            cmd = iterator.next(); // 获得下条命令
                            Log.d(TAG, "--------------->SendThread iterator.hasNext()yes");
                        } else { // 迭代器没有下条命令
                            Log.d(TAG, "--------------->SendThread iterator.hasNext()no");
                            if (oneTime) { // 只发送一次最后一条命令？
                                Log.d(TAG, "--------------->SendThread oneTime");
                                break; // 终止循环，发送线程停止
                            }
                        }
                        if (cmd != null) { // 如果命令不为null
                            if (retryCnt++ < 3) {
                                Log.d(TAG, "--------------->SendThread:" + DataCovertUtil.ByteArrToHex(cmd));
                                byte[] tempCmd = Arrays.copyOf(cmd, cmd.length);
                                byte addEM = ProtocolV3Utils.ADDRESS;
                                tempCmd[0] = addEM;
                                cmd = CRCChecker.getSendBuf(tempCmd);
                                send(cmd);
                                Log.d(TAG, "--------------->SendThread wait start");
                                Log.d(TAG, "--------------->SendThread wait end");
                            } else {
                                // 发送失败
                                break;
                            }
                        }
                    }
                    synchronized (this) {
                        if (mSendEndFlag) { // 发送线程停止flag=true？
                            break; // 终止循环，发送线程停止
                        }
                    }
                    Thread.sleep(mDataDelayTime);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                    break;
                }
            }
            Log.d(TAG, "--------------->send end");
            isRunEnd = true;
        }
    }
}